<?php
/**
 * datetime: 2022/4/17 12:06
 * user    : chenlong<vip_chenlong@163.com>
 **/

namespace App\Admin\Service\Base;

use App\Admin\Service\AbstractAdminService;
use App\Admin\Service\Traits\DestroyServiceTrait;
use App\Admin\Service\Traits\StoreServiceTrait;
use App\Admin\Service\Traits\UpdateServiceTrait;
use App\Common\Enums\Base\RouteEnumType;
use App\Common\Model\Base\Route;
use App\Common\Util\AdminAuth;
use App\Common\Util\EasySearch;
use App\Common\Util\TP;
use Psr\SimpleCache\InvalidArgumentException;
use Sc\Util\Tool;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 后台路由相关操作
 */
class RouteService extends AbstractAdminService
{
    use UpdateServiceTrait, StoreServiceTrait, DestroyServiceTrait;

    public function __construct()
    {
        $this->model = new Route();
    }

    public function lists(): array
    {
        $query = $this->model->order('weigh')->field(['title', 'id', 'pid', 'type', 'route', 'weigh', 'icon',]);

        $data = EasySearch::create($query)->totalCancellations()->getData();

        return ['data' => Tool::tree($data['data']->toArray())->getTreeData()];
    }

    public function beforeWrite(&$data, $id = null)
    {
        if (empty($data['pid'])) {
            $data['pid'] = 0;
        }
    }


    /**
     * 获取菜单数据
     *
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMenu(): array
    {
        $routes = $this->model->where('type', RouteEnumType::LeftMenu->value)
            ->order('weigh')->field([
                'id as `index`', 'title', 'route', 'pid', 'icon'
            ]);

        if (!AdminAuth::isSuper()) {
            $rolePermissionsService = RolePermissionsService::aop(false);
            $rolePermissionsService->init();
            $routes->whereIn('id', $rolePermissionsService->getRouteIdsByRoleIds(AdminAuth::getInfo()->role_ids));
        }
        $routes = $routes->select()->each(function ($route){
            $route->route = TP::route()->correctRule($route->route);
        });

        return Tool::tree($routes->toArray())->setNodeKey('index')->getTreeData();
    }

    /**
     * @return void
     * @throws InvalidArgumentException|\Throwable
     */
    public function afterWrite(): void
    {
        $rolePermissionsService = RolePermissionsService::aop(false);
        $rolePermissionsService->cacheRouteMapping(true);
        $rolePermissionsService->cacheRoleRouteIds(true);
    }
}
